local modname = ...
local M = {}
_G[modname] = M
package.loaded[modname] = M

local json = require "ac.json"
local base = require "ac.acctl_base"

local function restart_cat(s, reg)
	if not string.find(s, reg) then
		return s .. reg .. ";"
	else
		return s
	end
end

local function cmp_gencmd()
	local command = ""
	local change = false
	f = function (cmd, t1, t2, delete, section)
		for k1,v1 in pairs(t1) do
			local v2 = t2[k1]
			if v1 ~= v2 then
				if type(v1) == "table" and type(v2) == "table" then
					f(cmd, v1, v2, delete, k1)
				elseif v2 == nil and type(v1) == "table" then
					if delete then
						t1[k1]={}
						command = command .. cmd.del
						command = string.gsub(command, "<section>", k1)
						command = command .. ";"
						change = true
						return change,command
					else
						t2[k1]={}
						command = command .. cmd.new
						command = string.gsub(command, "<section>", k1)
						command = command .. ";"
						change = true
						f(cmd, v1, t2[k1], delete, k1)
					end
				else
					t2[k1] = v1
					command = command .. cmd.set
					command = string.gsub(command, "<section>", section)
					command = string.gsub(command, "<option>", k1)
					command = command .. "=" .. v1
					command = command .. ";"
					change = true
				end
			end
		end
		return change,command
	end
	return f
end

local function cmp_element()
	local f = cmp_gencmd()
	return function(cmd, t1, t2)
			f(cmd, t2, t1)
			return f(cmd, t1, t2, 1)
		end
end

function M.statussync(s, d)
	local restart = ""
	local command = ""
	local needrestart = false
	local change = false

	local f = cmp_element()

	if f(base.network, s.network, d.network) then
		restart = restart_cat(restart, base.network.restart)
		needrestart = true
	end

	if f(base.wireless, s.wireless, d.wireless) then
		restart = restart_cat(restart, base.wireless.restart)
	end

	if f(base.switch, s.switch, d.switch) then
		restart = restart_cat(restart, base.switch.restart)
	end

	change, command = f(base.vlan, s.vlan, d.vlan)
	if change then
		restart = restart_cat(restart, base.vlan.restart)
	end

	if command ~= "" then
		command = command .. "uci commit;" .. restart
		print("LUA:" .. command)
	end

	return needrestart, command
end

function M.netsync(s, d)
	local restart = ""
	local command = ""
	local needrestart = false
	local change = false

	local f = cmp_gencmd()

	change, restart = f(base.network, s, d)
	if change then
		restart = restart_cat(restart, base.network.restart)
		needrestart = true
	end

	if command ~= "" then
		command = command .. "uci commit;" .. restart
		print("LUA:" .. command)
	end
	return needrestart, command
end

--[=[
str1 = [[ {"switch":{"cfg053777":{"name":"switch0"}},"vlan":[],"network":{"loopback":{"netmask":"255.0.0.0","ipaddr":"127.0.0.1"},"lan":{"netmask":"255.255.0.0","ipaddr":"192.168.16.1","gateway":"192.168.16.10"}},"wireless":{"cfg033579":{"ssid":"AnyWiFi-Not-Free","encryption":"none"}}} ]]

str2 = [[ {"switch":{"cfg053777":{"name":"switch0"}},"vlan":{"vlan0":{"ipaddr":"192.168.2.1"}},"network":{"loopback":{"netmask":"255.255.0.0","ipaddr":"127.0.0.1"},"lan":{"netmask":"255.255.0.0","ipaddr":"192.168.16.1","gateway":"192.168.16.10"}},"wireless":{"cfg033579":{"ssid":"AnyWiFi-Not-Free","encryption":"none"}}} ]]

print(sync(json.decode(str1), json.decode(str2)))
--]=]
